﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Styx.WoWInternals;

namespace FelMaster
{
    public class LuaChannel
    {
        private string channelName = null;
        private Dictionary<string, string> commands = new Dictionary<string, string>();

        private static LuaChannel instance = new LuaChannel();
        public static LuaChannel Instance
        {
            get
            {
                return instance;
            }
        }

        private Random rand = new Random();
        private string randomString (int length)
        {
            var x = "";
            var chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_".ToCharArray();
            for (var i = 0; i < length; i++)
            {
                var j = chars[rand.Next(0, chars.Length)];
                x += j;
            }
            return x;
        }

        private LuaChannel()
        {
            channelName = randomString(16);
        }

        public void BindEvents()
        {
            Lua.Events.AttachEvent("CHAT_MSG_ADDON", CHAT_MSG_ADDON);
        }
        public void UnbindEvents()
        {
            Lua.Events.DetachEvent("CHAT_MSG_ADDON", CHAT_MSG_ADDON);
        }

        private void CHAT_MSG_ADDON(object sender, LuaEventArgs raw)
        {
            var args = raw.Args;
            var prefix = Convert.ToString(args[0]);
            if (prefix != channelName)
                return;

            var sendType = Convert.ToString(args[2]).ToUpper();
            if (sendType != "WHISPER")
                return;

            var msg = Convert.ToString(args[1]);
            if (!commands.ContainsValue(msg))
                return;

            var command = commands.First(x => x.Value == msg).Key;
            var callback = callbacks[command];
            callback.Invoke(null);
        }

        public delegate void OnChannelMessageDelegate(object context);

        private Dictionary<string, OnChannelMessageDelegate> callbacks = new Dictionary<string, OnChannelMessageDelegate>();
        public void Bind(string command, OnChannelMessageDelegate callback)
        {
            commands[command] = randomString(10);
            callbacks[command] = callback;
        }

        private void AddUserMacro(string command)
        {
            var chunk = commands[command];
            var lua = "/script SendAddonMessage(\"{0}\",\"{1}\",\"WHISPER\",\"{2}\")";
            lua = string.Format(lua, SimCraftBase.RealLuaEscape(channelName), SimCraftBase.RealLuaEscape(chunk), SimCraftBase.RealLuaEscape(ObjectManager.Me.Name));

            var name = command;

            //delete it, if any
            Lua.DoString("DeleteMacro(\"" + SimCraftBase.RealLuaEscape(name) + "\")");

            //create it and dont store it on blizz server. Use the WTF folder instead.
            Lua.DoString(string.Format("CreateMacro(\"{0}\", 42, \"{1}\", nil, nil)",
                SimCraftBase.RealLuaEscape(name), SimCraftBase.RealLuaEscape(lua)));
        }

        public void AddAllUserMacros()
        {
            foreach (var name in commands.Keys)
            {
                AddUserMacro(name);
            }
        }

        public void RemoveAllUserMacros()
        {
            foreach (var name in commands.Keys)
            {
                Lua.DoString("DeleteMacro(\"" + SimCraftBase.RealLuaEscape(name) + "\")");
            }
        }
    }
}
